package com.eptok.weixin.service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import com.eptok.weixin.util.HuaBan;

import yspay.express.store.WxStore;

public class ImageService {

	public static void main(String[] args) {
		try {
			upload();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private static String up_temporary_url = "https://api.weixin.qq.com/cgi-bin/media/upload";  
	
	public static String upload() throws Exception {  
		 String ret = "";
        // 获得utf-8编码的mbuilder  
        MultipartEntityBuilder mBuilder = get_COMPATIBLE_Builder("UTF-8");  
        /** 
         * 原生的微信使用的url是https://api.weixin.qq.com/cgi-bin/media/upload? 
         * access_token=##ACCESS_TOKEN##&type=##TYPE## 
         * 一般都会使用这个把参数直接携带在url中。我个人不喜欢这样，因为既然使用了httpclient，完全可以把参数 
         * 设置在我们的body体中。所以我们使用的url是这样的 
         * https://api.weixin.qq.com/cgi-bin/media/upload 然后通过在body体中设置参数来设置 
         * access_token和type这两个字段 
         *  
         * */  
        // 设置type，我这里用一个缩略图来做实验，所以type是thumb  
        mBuilder.addTextBody("type", "image");  
        // 设置access_token，  
        mBuilder.addTextBody("access_token", WxStore.getAccessToken());  
        // 这里就是我要上传到服务器的多媒体图片  
        File f = getFile();
        System.out.println(f.length()/1024+"K");
        mBuilder.addBinaryBody("media", f,  
                ContentType.APPLICATION_OCTET_STREAM, f  
                        .getName());  
        // 建造我们的http多媒体对象  
        HttpEntity he = mBuilder.build();  
        // 建立一个sslcontext，这里我们信任任何的证书。  
        SSLContext context = getTrustAllSSLContext();  
        // 建立socket工厂  
        SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(  
                context);  
        // 建立连接器  
        CloseableHttpClient client = HttpClients.custom()  
                .setSSLSocketFactory(factory).build();  
        try {  
            // 得到一个post请求的实体  
            HttpPost post = getMultipartPost();  
            // 给请求添加参数  
            post.setEntity(he);  
            // 执行请求并获得结果  
            CloseableHttpResponse reponse = client.execute(post);  
            try {  
                // 获得返回的内容  
                HttpEntity entity = reponse.getEntity();  
                // 输出  
                ret = EntityUtils.toString(entity);
                System.out.println(ret);
                // 消耗实体  
                EntityUtils.consume(entity);  
            } finally {  
                // 关闭返回的reponse  
                reponse.close();  
            }  
        } finally {  
            // 关闭client  
            client.close();  
        } 
        return ret;
    }  
	
	
	private static String getBoundaryStr(String str) {  
	    return "------------" + str;  
	}  
	  
	private static File getFile() {
		try {
			String path = HuaBan.getImgRoundHB("清纯美女");
			download(path, "wximage.jpg", "c://");
			File f = new File("c://wximage.jpg");
			return f;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	 public static void download(String urlString, String filename,String savePath) throws Exception {  
	        // 构造URL  
	        URL url = new URL(urlString);  
	        // 打开连接  
	        URLConnection con = url.openConnection();  
	        //设置请求超时为5s  
	        con.setConnectTimeout(5*1000);  
	        // 输入流  
	        InputStream is = con.getInputStream();  
	      
	        // 1K的数据缓冲  
	        byte[] bs = new byte[1024];  
	        // 读取到的数据长度  
	        int len;  
	        // 输出的文件流  
	       File sf=new File(savePath);  
	       if(!sf.exists()){  
	           sf.mkdirs();  
	       }  
	       OutputStream os = new FileOutputStream(sf.getPath()+"\\"+filename);  
	        // 开始读取  
	        while ((len = is.read(bs)) != -1) {  
	          os.write(bs, 0, len);  
	        }  
	        // 完毕，关闭所有链接  
	        os.close();  
	        is.close();  
	    }   
	  
	  
	private static MultipartEntityBuilder get_COMPATIBLE_Builder(String charSet) {  
	    MultipartEntityBuilder result = MultipartEntityBuilder.create();  
	    result.setBoundary(getBoundaryStr("7da2e536604c8"))  
	            .setCharset(Charset.forName(charSet))  
	            .setMode(HttpMultipartMode.BROWSER_COMPATIBLE);  
	    return result;  
	}  
	  
	  
	private static HttpPost getMultipartPost() {  
	    /* 这里设置一些post的头部信息，具体求百度吧 */  
	    HttpPost post = new HttpPost(up_temporary_url);  
	    post.addHeader("Connection", "keep-alive");  
	    post.addHeader("Accept", "*/*");  
	    post.addHeader("Content-Type", "multipart/form-data;boundary="  
	            + getBoundaryStr("7da2e536604c8"));  
	    post.addHeader("User-Agent",  
	            "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");  
	    return post;  
	}  
	  
	private static SSLContext getTrustAllSSLContext() throws Exception {  
	    SSLContext context = SSLContexts.custom()  
	            .loadTrustMaterial(null, new TrustStrategy() {  
	                @Override  
	                public boolean isTrusted(X509Certificate[] arg0, String arg1)  
	                        throws CertificateException {  
	                    // 这一句就是信任任何的证书，当然你也可以去验证微信服务器的真实性  
	                    return true;  
	                }  
	            }).build();  
	    return context;  
	}  
	
}
